package org.wattdepot.cli;

import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClientException;
import org.wattdepot.util.tstamp.Tstamp;

/**
 * Executes the carboncontent command.
 * 
 * @author Scott Wong and Kelli Sawai
 * 
 */
public class CarbonData extends CommandLineInterface implements WattDepotCliCommand {

  /**
   * Executes and returns the results of the carboncontent command.
   * 
   * @param args The arguments required to execute this method.
   * @return The results of the command.
   */
  public String doCommand(String args) {
    try {
      if (args.matches("carboncontent \\w* \\S* sampling-interval \\d*")) {
        String[] temp = args.split("\\s");
        String source = temp[1];
        int interval = Integer.parseInt(temp[4]);

        XMLGregorianCalendar startTime = toTimestamp(temp[2]);
        // Check if the timestamp is in the future.
        XMLGregorianCalendar now =
            DatatypeFactory.newInstance()
                .newXMLGregorianCalendar(new GregorianCalendar());
        if (startTime.compare(now) >= 0) {
          return futureTimestampMessage;
        }
        // creates an end timestamp an hour after the start time.
        XMLGregorianCalendar endTime = startTime;
        endTime = Tstamp.incrementHours(endTime, 1);
        // calculates the carbon content for the hour.
        double content = calculateCarbonContent(source, startTime, endTime, interval);

        return content + " lbs CO2/MWh";
      }
      else {
        return "The command you have entered is invalid.";
      }
    }
    catch (ResourceNotFoundException e) {
      return resourceMessage;
    }
    catch (WattDepotClientException e) {
      return "An error occured while executing the requested command.";
    }
    catch (Exception e) {
      return "An error occured while executing the requested command.";
    }
  }

  /**
   * Calculates the carbon content for a given hour.
   * 
   * @param src The plant to draw data from.
   * @param start The starting time.
   * @param end The ending time.
   * @param time The sampling interval.
   * @return The carbon content for the hour.
   * @throws MiscClientException All other exceptions.
   * @throws BadXmlException If there is a bad xml file.
   * @throws ResourceNotFoundException If the date doesn't exist.
   * @throws NotAuthorizedException If the user is not authorized to access the data.
   */
  private double calculateCarbonContent(String src, XMLGregorianCalendar start,
      XMLGregorianCalendar end, int time) throws NotAuthorizedException,
      ResourceNotFoundException, BadXmlException, MiscClientException {
    // calculates how much carbon is produced.
    double carbon = client.getCarbonEmitted(src, start, end, time);
    // calculates how much energy is produced.
    double energy = client.getEnergyGenerated(src, start, end, time);
    // convert from Wh to MWh
    energy = energy / 1000000;
    // calculates the carbon content for the given time.
    return (carbon / energy);
  }
}
